local ByteArray = require("framework.cc.utils.ByteArray");
local SocketTCP = require("framework.cc.net.init").SocketTCP;
local Packet = require(SCRIPTS_DIR .. ".network.Packet")


local m_isPacketFull = true;
local tmpPacket = nil;


local TcpNet = class("TcpNet")
function TcpNet:ctor()
    -- body
    self.socket = nil;
end


function TcpNet:init()
    -- body
    mgrs.log:printDebug("socket time:" .. SocketTCP.getTime());
    mgrs.log:printDebug("os time:" .. os.time());
    local socket = SocketTCP.new();
    socket:setName("GameTcp");
    --socket:setTickTime(1);
    --socket:setReconnTime(6);
    socket:setConnFailTime(4);
    socket:addEventListener(SocketTCP.EVENT_DATA, handler(self,self.tcpReceive));
    socket:addEventListener(SocketTCP.EVENT_CLOSE, handler(self,self.tcpClose));
    socket:addEventListener(SocketTCP.EVENT_CLOSED, handler(self,self.tcpClosed));
    socket:addEventListener(SocketTCP.EVENT_CONNECTED, handler(self,self.tcpConnected));
    socket:addEventListener(SocketTCP.EVENT_CONNECT_FAILURE, handler(self,self.tcpError));
    mgrs.log:printDebug("version is " .. SocketTCP._VERSION);
    self.socket = socket;
    SocketTCP._DEBUG = true;
end


function TcpNet:connectSocket(host, port)
    -- body
    self:init();
    self.socket:connect(host, port, false);
end



function TcpNet:tcpClose(event)
    -- body
    mgrs.proto:socketExit();
end

function TcpNet:tcpClosed(event)
    -- body
    mgrs.proto:socketClosed();
end

function TcpNet:tcpConnected(event)
    -- body
    mgrs.proto:socketSucess();
end

function TcpNet:tcpError(event)
    -- body
    mgrs.proto:socketError();
end

--tcp直接shutdown();
function TcpNet:closeSocket()
    -- body
    self:close();
    self.socket:disconnect();--会接收到SocketTCP.EVENT_CLOSED事件触发scnet.tcpClosed()
end

--关闭定时器
function TcpNet:close()
    -- body
    if self.socket.isConnected then
        self.socket:close();--会接收到SocketTCP.EVENT_CLOSE事件触发scnet.tcpClose()
    end
end


function TcpNet:dispatchData(buf)
    -- body
    local pack = Packet:new();
    pack:pWriteBuf(buf);
    pack:setPos(1);
    local protoId = pack:pReadProtoId();
    mgrs.log:printDebug("protoID = " .. protoId);
    mgrs.proto:receive(protoId,pack);
end



function TcpNet:doNetDatas(pack)
    --粘包问题处理
    if m_isPacketFull then
        local realLen = pack:getLen() - 4;
        if realLen < 0 then
            -- body
            mgrs.log:printError("数据包有问题");
            return;
        end
        local needLen = pack:pReadLength();
        if realLen >= needLen then
            -- 足够的包
            local curDataBuf = pack:readBuf(needLen);
            self:dispatchData(curDataBuf);
            --处理剩余数据
            if realLen ~= needLen then
                local nPack = Packet:new();
                local buff = pack:readBuf(realLen - needLen);
                nPack:writeBuf(buff);
                pack = nil;
                nPack:setPos(1);
                self:doNetDatas(nPack);
            end
        else
            -- 数据不够一条 等待下一条数据
            m_isPacketFull = false;
            tmpPacket = pack;
            mgrs.log:printDebug("半包数据:" .. tmpPacket:toString() .. "等待下一条数据");
        end
    else
        --半包 要组包
        m_isPacketFull = true;
        local nPack = Packet:new();
        nPack:writeBytes(tmpPacket);
        tmpPacket = nil;
        nPack:writeBytes(pack);
        pack = nil;
        nPack:setPos(1);
        mgrs.log:printDebug("组包数据:" .. nPack:toString() .. "  解析开始");
        self:doNetDatas(nPack);
    end
end


-- 接收数据
function TcpNet:tcpReceive(event)
    -- body
    local pack = Packet:new();
    pack:pWriteBuf(event.data);
    pack:setPos(1);
    mgrs.log:printDebug("recvData:" .. pack:toString());
    self:doNetDatas(pack);
end

-- 发送数据 msgid 消息id,data 消息数据
function TcpNet:sendData(data)
    -- body
    self.socket:send(data);
end



return TcpNet;

--endregion
